﻿using CmccTool.KPI.DbTables;
using CmccTool.KPI.Services;
using CmccTool.Services;
using Microsoft.Data.Sqlite;
using SQLite;
using SQLitePCL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static CmccTool.KPI.DbTables.KpiTables;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;



namespace CmccTool.KPI.View
{
    public partial class ErrCellAnalysis : UserControl
    {
        #region 公共变量
        private readonly SQLiteConnection? _db = KpiImpHelper.KpiDbChh();
        private KpiQuertHelper _quertHelper = new();
        private readonly BindingSource _bdErrCell = new BindingSource();

        private string ErrType = string.Empty; // 质差类型
        private string ErrName = string.Empty; // 质差类型
        private ErrCell selectedErrCell = null!; // 选中的行转换为 ErrCell 对象
        private ErrNode selectedErrNodeUp = null!; // 选中的 ErrNode 对象
        private ErrNode selectedErrNodeDown = null!; // 选中的 ErrNode 对象
        // 添加取消支持
        private CancellationTokenSource _cts = null!;

        // 根据错误类型获取源表名
        private string GetSourceTableName(string ErrName)
        {
            return ErrName switch
            {
                "4G低流量" => "KpiXwyLteLd",
                "5G低流量" => "KpiXwyNrLd",
                "5G低效益" => "KpiXwyNrDx",
                _ => string.Empty // 默认表
            };
        }
        #endregion

        // 初始化组件
        public ErrCellAnalysis()
        {
            InitializeComponent();
            // 设置下拉选项
            CmbErrName.Items.AddRange(["4G低流量", "5G低流量", "5G低效益"]);
            CmbErrName.SelectedIndex = 0;
            // 设置DataGridView为虚拟模式（大容量数据时可选）
            dgViewErrCell.VirtualMode = true;
            dgViewErrCell.RowPrePaint += (s, e) => { /* 禁用行自绘提升性能 */ };
            SetDoubleBuffered(dgViewErrCell);
            // 绑定 DataGridView
            dgViewErrCell.DataSource = _bdErrCell;
            dgViewErrCell.AutoGenerateColumns = true; // 自动生成列（或手动配置）
            // 初始化右键菜单
            createMenuStrip();
            //
            cmbStatus.Items.AddRange(["当日新增", "当日恢复", "最新恢复", "未闭环", "分析", "分发处理", "已处理", "已确认", "观察", "闭环?", "闭环", string.Empty]);
            cmbStatus.SelectedIndex = 0;
        }

        // 双缓冲技术
        private static void SetDoubleBuffered(Control control)
        {
            if (SystemInformation.TerminalServerSession) return;
            var prop = typeof(Control).GetProperty("DoubleBuffered",
                System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Instance);
            prop?.SetValue(control, true, null);
        }


        #region 按钮

        // 异步按钮点击事件-更新质差小区数据
        private async void BtnQuery_ClickAsync(object sender, EventArgs e)
        {
            // 禁用按钮防止重复点击
            BtnQuery.Enabled = false;

            try
            {
                await ProcessDataAsync(); // 核心异步方法
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败: {ex.Message}");
            }
            finally
            {
                BtnQuery.Enabled = true; // 恢复按钮
                // 刷新错误小区列表
                string ErrName = CmbErrName.SelectedItem?.ToString() ?? "4G低流量";
                RefreshErrCellList(ErrName);
            }


        }

        // 筛选质差小区按钮
        private void btnErrcellQuery_Click(object sender, EventArgs e)
        {
            updateLeftUp();
        }

        #endregion

        #region 同步方法，保留参考，未使用
        // 原同步方法，保留以备参考
        private void BtnQuery_Click(object sender, EventArgs e)
        {
            // 同步处理
            _cts = new CancellationTokenSource();
            //ProcessData();
            string ErrName = CmbErrName.SelectedItem?.ToString() ?? "4G低流量";
            string chhDate = "2025-01-01";


            //  获取对应kpi表
            string tabName = GetSourceTableName(ErrName);
            if (string.IsNullOrEmpty(tabName)) { MessageBox.Show("质差类型未识别!"); return; }
            // 获取最新日期
            if (_db == null)
            {
                MessageBox.Show("数据库初始化失败");
                return;
            }
            //确认 更新开始日期 和 闭环标记
            var errCount = _db.Table<ErrCell>().Count();

            //直接使用索引列排序获取最大值，比 MAX()更高效：
            // errCell结束日期最大值的后一天作为开始日期
            string dateSta = _db.ExecuteScalar<string>($"SELECT 结束日期 FROM ErrCell where 质差名称='{ErrName}' ORDER BY 结束日期 DESC LIMIT 1");

            // 根据dateSta取值情况，确认当前状态
            string StrEndStatasFlag = string.Empty;
            if (string.IsNullOrEmpty(dateSta))
            {
                StrEndStatasFlag = "闭环";
                dateSta = chhDate;
            }
            else
            {
                StrEndStatasFlag = "闭环";
            }
            // 数据源表日期最大值作为更新的最后结果
            string dateEnd = _db.ExecuteScalar<string>($"SELECT date FROM {tabName} ORDER BY date DESC LIMIT 1");
            if (string.IsNullOrEmpty(dateEnd)) { MessageBox.Show($"{ErrName}({tabName}):无有效数据"); return; }
            // 1. 安全解析日期（防止空值或格式错误）
            DateTime dateStaDt, dataEndDt;
            if (!DateTime.TryParse(dateSta, out dateStaDt) ||
                !DateTime.TryParse(dateEnd, out dataEndDt))
            {
                MessageBox.Show($"日期格式无效，请检查数据库.{Environment.NewLine}质差小区最后日期:{dateSta};{Environment.NewLine}{ErrName}({tabName})结束日期:{dateEnd}");
                return;
            }



            // 2. 确保日期顺序（避免反向循环）
            dateStaDt = dateStaDt.AddDays(1);
            if (dateStaDt > dataEndDt)
            {
                MessageBox.Show($"源数据日期晚于更新表日期，请检查数据库.{Environment.NewLine}质差小区最后日期:{dateSta};{Environment.NewLine}{ErrName}({tabName})结束日期:{dateEnd}");
                return;
            }

            // 设置进度表
            progressBar.Minimum = 0;
            progressBar.Maximum = (dataEndDt - dateStaDt).Days + 1;
            progressBar.Value = 0;

            // 3. 循环处理每日数据

            for (DateTime currentDate = dateStaDt;
            currentDate <= dataEndDt;
            currentDate = currentDate.AddDays(1))
            {
                string currentDateStr = currentDate.ToString("yyyy-MM-dd");

                // 获取质差小区明细
                DataTable ErrCellsImpDt = _quertHelper.QueryDataBysql($"Select * from {tabName} where date = '{currentDateStr}' ");
                if (ErrCellsImpDt != null && ErrCellsImpDt.Rows.Count > 0) { } else { continue; }//无有效数据则下一日

                List<ErrCell> ErrCellsImp = ErrCell.transtErrcellFromDataRows(ErrCellsImpDt, ErrName, tabName);

                // 获取待添加数据
                List<ErrCell> ErrCellListExists = _db.Table<ErrCell>().Where(c => c.ErrName == ErrName && c.Status != "闭环").ToList();
                var existingDict = ErrCellListExists.ToDictionary(e => e.CGI);

                // 完善消失的部分
                // 使用HashSet替代List.Any()提升查找性能[6](@ref)
                var newCgis = new HashSet<string>(ErrCellsImp.Select(n => n.CGI));
                var disappeared = existingDict.Values
                    .Where(e => !newCgis.Contains(e.CGI)) // O(1)查找复杂度
                    .ToList();


                try
                {
                    _db.BeginTransaction();
                    // 完善消失的部分
                    foreach (var cell in disappeared)
                    {
                        cell.Status = StrEndStatasFlag;
                        _db.Update(cell);
                    }

                    // 更新新增的部分
                    int rowId = 0;
                    foreach (ErrCell newCell in ErrCellsImp)
                    {
                        var cgi = newCell.CGI;
                        rowId++;
                        //
                        if (existingDict.TryGetValue(cgi, out var existing))
                        {

                            // 更新现有记录
                            existing.EndDate = newCell.EndDate;
                            existing.LatestValue = newCell.LatestValue;
                            existing.DurationDays = newCell.DurationDays;
                            // 自动计算天数[1](@ref)
                            if (DateTime.TryParse(existing.StartDate, out DateTime start) &&
                                DateTime.TryParse(existing.EndDate, out DateTime end))
                            {
                                existing.DurationDays = (end - start).Days + 1;
                            }
                            //
                            _db.Update(existing);
                        }
                        else
                        {
                            // 新增记录
                            _db.Insert(newCell);
                            ErrCellListExists.Add(newCell);
                            existingDict.Add(newCell.CGI, newCell);
                        }
                    }

                    _db.Commit();
                    progressBar.Value += 1;
                    labelStatus.Text = $"更新{currentDateStr}：{ErrCellsImpDt.Rows.Count}条数据";
                }
                catch (SQLiteException ex)
                {
                    _db.Rollback(); // 回滚所有更改
                    MessageBox.Show($"数据库错误：导入{currentDateStr}数据时{Environment.NewLine}{ex.Message}");
                    return;
                }
                catch (Exception ex)
                {
                    _db.Rollback();
                    MessageBox.Show($"系统错误：导入{currentDateStr}数据时{Environment.NewLine}{ex.Message}");
                    return;
                }
            }



            MessageBox.Show("完成");
        }

        #endregion

        #region 质差小区增量更新-核心异步处理方法
        private async Task ProcessDataAsync()
        {
            // 保护性检查
            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            //
            int isVacation = chbVacation.Checked ? 1 : 0;
            string ErrName = CmbErrName.SelectedItem?.ToString() ?? "4G低流量";
            string chhDate = "2025-01-01";


            //  获取对应kpi表
            string tabName = GetSourceTableName(ErrName);
            if (string.IsNullOrEmpty(tabName)) { MessageBox.Show("质差类型未识别!"); return; }
            // 获取最新日期
            if (_db == null)
            {
                MessageBox.Show("数据库初始化失败");
                return;
            }
            //确认 更新开始日期 和 闭环标记
            var errCount = _db.Table<ErrCell>().Count();

            //直接使用索引列排序获取最大值，比 MAX()更高效：
            // errCell结束日期最大值的后一天作为开始日期
            string dateSta = _db.ExecuteScalar<string>($"SELECT 结束日期 FROM ErrCell where 质差名称='{ErrName}' ORDER BY 结束日期 DESC LIMIT 1");

            // 根据dateSta取值情况，确认当前状态
            string StrEndStatasFlag = string.Empty;
            if (string.IsNullOrEmpty(dateSta))
            {
                StrEndStatasFlag = "闭环";
                dateSta = chhDate;
            }
            else
            {
                StrEndStatasFlag = "闭环?";
            }
            // 数据源表日期最大值作为更新的最后结果
            string dateEnd = _db.ExecuteScalar<string>($"SELECT date FROM {tabName} ORDER BY date DESC LIMIT 1");
            if (string.IsNullOrEmpty(dateEnd)) { MessageBox.Show($"{ErrName}({tabName}):无有效数据"); return; }
            // 1. 安全解析日期（防止空值或格式错误）
            DateTime dateStaDt, dataEndDt;
            if (!DateTime.TryParse(dateSta, out dateStaDt) ||
                !DateTime.TryParse(dateEnd, out dataEndDt))
            {
                MessageBox.Show($"日期格式无效，请检查数据库.{Environment.NewLine}质差小区最后日期:{dateSta};{Environment.NewLine}{ErrName}({tabName})结束日期:{dateEnd}");
                return;
            }

            // 2. 确保日期顺序（避免反向循环）
            dateStaDt = dateStaDt.AddDays(1);
            if (dateStaDt > dataEndDt)
            {
                MessageBox.Show($"源数据日期晚于更新表日期，请检查数据库.{Environment.NewLine}质差小区最后日期:{dateSta};{Environment.NewLine}{ErrName}({tabName})结束日期:{dateEnd}");
                return;
            }


            // 使用Progress实现跨线程UI更新
            IProgress<(int value, string message)> progress = new Progress<(int value, string message)>(report =>
            {
                progressBar.Value = report.value;
                labelStatus.Text = $"{report.value * 100 / progressBar.Maximum:F2}%:{report.message}";
            });

            progressBar.Minimum = 0;
            progressBar.Maximum = (dataEndDt - dateStaDt).Days + 1;

            // 启动异步任务
            await Task.Run(() =>
            {
                for (DateTime currentDate = dateStaDt; currentDate <= dataEndDt; currentDate = currentDate.AddDays(1))
                {
                    progress.Report(((currentDate - dateStaDt).Days + 1, $"正在处理 {currentDate:yyyy-MM-dd}..."));

                    // 4. 同步处理单日数据（保持事务原子性）
                    ProcessSingleDay(currentDate, ErrName, tabName, StrEndStatasFlag, isVacation);
                }
            });

            // 5. 最终状态更新
            labelStatus.Text = "更新完成！";
            MessageBox.Show("操作完成");
        }

        // 单日数据处理方法（保持同步事务）
        private void ProcessSingleDay(DateTime currentDate, string ErrName, string tabName, string StrEndStatasFlag = "闭环", int isVacation = 0)
        {
            // 保护性检查
            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            //
            string currentDateStr = currentDate.ToString("yyyy-MM-dd");
            // ... [原有单日数据处理逻辑，包括数据库事务]

            // 获取质差小区明细
            DataTable ErrCellsImpDt = _quertHelper.QueryDataBysql($"Select * from {tabName} where date = '{currentDateStr}' ");
            if (ErrCellsImpDt != null && ErrCellsImpDt.Rows.Count > 0) { } else { return; }//无有效数据则下一日

            List<ErrCell> ErrCellsImp = ErrCell.transtErrcellFromDataRows(ErrCellsImpDt, ErrName, tabName, isVacation);

            // 获取待添加数据
            List<ErrCell> ErrCellListExists = _db.Table<ErrCell>().Where(c => c.ErrName == ErrName && !c.Status.Contains("闭环")).ToList();
            var existingDict = ErrCellListExists.ToDictionary(e => e.CGI);

            // 完善消失的部分
            // 使用HashSet替代List.Any()提升查找性能[6](@ref)
            var newCgis = new HashSet<string>(ErrCellsImp.Select(n => n.CGI));
            var disappeared = existingDict.Values
                .Where(e => !newCgis.Contains(e.CGI)) // O(1)查找复杂度
                .ToList();

            try
            {
                _db.BeginTransaction();
                // 完善消失的部分
                foreach (var cell in disappeared)
                {
                    cell.Status = StrEndStatasFlag;
                    _db.Update(cell);
                }

                // 更新新增的部分
                int rowId = 0;
                foreach (ErrCell newCell in ErrCellsImp)
                {
                    var cgi = newCell.CGI;
                    rowId++;
                    //
                    if (existingDict.TryGetValue(cgi, out var existing))
                    {

                        existing.EndDate = newCell.EndDate;
                        existing.ErrValue = newCell.ErrValue;
                        existing.DurationDays = newCell.DurationDays;
                        existing.ErrType = newCell.ErrType;

                        if (string.IsNullOrEmpty(existing.GcCellName))
                        {
                            existing.GcCellName = _db.ExecuteScalar<string>($"select 工参小区 from GcCgiInfo where GcCgiInfo.Cgi = '{cgi}' ");
                        }

                        existing.Scene = newCell.Scene;
                        existing.IsSchool = newCell.IsSchool;


                        // 自动计算天数[1](@ref)
                        if (DateTime.TryParse(existing.StartDate, out DateTime start) &&
                            DateTime.TryParse(existing.EndDate, out DateTime end))
                        {
                            existing.DurationDays = (end - start).Days + 1;
                        }
                        //
                        _db.Update(existing);
                    }
                    else
                    {
                        // 新增记录
                        newCell.GcCellName = _db.ExecuteScalar<string>($"select 工参小区 from GcCgiInfo where GcCgiInfo.Cgi = '{cgi}' ");
                        _db.Insert(newCell);
                        ErrCellListExists.Add(newCell);
                        existingDict.Add(newCell.CGI, newCell);
                    }
                }

                _db.Commit();
            }
            catch (SQLiteException ex)
            {
                _db.Rollback(); // 回滚所有更改
                MessageBox.Show($"数据库错误：导入{currentDateStr}数据时{Environment.NewLine}{ex.Message}");
                return;
            }
            catch (Exception ex)
            {
                _db.Rollback();
                MessageBox.Show($"系统错误：导入{currentDateStr}数据时{Environment.NewLine}{ex.Message}");
                return;
            }
        }

        #endregion

        #region 处理 DataGridView 单元格点击事件
        // 处理 DataGridView 单元格点击事件
        private void dgViewErrCell_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0) // 排除点击行头/列头
            {
                DataGridViewRow selectedRow = dgViewErrCell.Rows[e.RowIndex];
                // 提取所需字段值（假设列名分别为 "CGI"、"StartDate"、"Duration"）
                string cgi = selectedRow.Cells["CGI"].Value?.ToString() ?? "N/A";
                string startDate = selectedRow.Cells["StartDate"].Value?.ToString() ?? "N/A";
                string DurationDays = selectedRow.Cells["DurationDays"].Value?.ToString() ?? "N/A";
                string GcCellName = selectedRow.Cells["GcCellName"].Value?.ToString() ?? "N/A";

                // 更新参数
                selectedErrCell = ErrCell.transtErrcellFromDataGridViewRow(selectedRow);

                // 更新-左下
                updateTabControlLeftDown();

                // 更新-右上
                updateRightUp();

                // 更新-右下
                updateRightDown();

                // 拼接信息并更新 TextBox
                string ErrName = CmbErrName.SelectedItem?.ToString() ?? "NA";
                txbErrCellInfo.Text = $"{cgi}({GcCellName}):{startDate}出现【{ErrName}】,持续【{DurationDays}】天\n";
            }
        }


        private void dgViewRightUp_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0) // 排除点击行头/列头
            {
                DataGridViewRow selectedRow = dgViewRightUp.Rows[e.RowIndex];
                selectedErrNodeUp = ErrNode.transtErrNodeFromDataGridViewRow(selectedRow);
            }
        }

        private void dgViewRightDown_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0) // 排除点击行头/列头
            {
                DataGridViewRow selectedRow = dgViewRightDown.Rows[e.RowIndex];
                selectedErrNodeDown = ErrNode.transtErrNodeFromDataGridViewRow(selectedRow);
            }
        }
        #endregion

        #region 处理下拉框选项变化事件
        private void CmbErrName_SelectedIndexChanged(object sender, EventArgs e)
        {
            ErrName = CmbErrName.SelectedItem?.ToString() ?? "4G低流量";
            switch (ErrName)
            {
                case "4G低流量" or "5G低流量":
                    cmbErrType.Items.Clear();
                    cmbErrType.Items.AddRange(["低流量", "零流量", string.Empty]);
                    break;
                case "5G低效益":
                    cmbErrType.Items.Clear();
                    cmbErrType.Items.AddRange(["低效益", "零效益", string.Empty]);
                    break;
            }

            cmbErrType.Text = string.Empty;
            ErrType = string.Empty;

            updateLeftUp();
        }

        private void cmbErrType_SelectedIndexChanged(object sender, EventArgs e)
        {

            updateLeftUp();
        }

        private void cmbStatus_SelectedIndexChanged(object sender, EventArgs e)
        {
            updateLeftUp();
        }
        #endregion


        #region 左下-LeftDown 选项卡处理

        private void tabControlKpi_Selected(object sender, TabControlEventArgs e)
        {
            updateTabControlLeftDown();

        }

        private void updateTabControlLeftDown()
        {
            var selectedTabName = tabControlLeftDown.SelectedTab?.Name ?? string.Empty;
            switch (selectedTabName)
            {
                case "tabPageXwyCell":
                    // 更新 关联的 cgi 的 dgViewXwyCell kpi 明细
                    updateTabControlLeftDownXwyCell();
                    break;
                case "tabPageXwyNode":
                    // 更新 关联的 cgi 的 dgViewXwyCell kpi 明细
                    updateTabControlLeftDownXwyNode();
                    break;
                default:
                    break;
            }
        }

        private void updateTabControlLeftDownXwyNode()
        {
            dgViewLeftDownXwyNode.DataSource = null;
            dgViewLeftDownXwyNode.Rows.Clear(); // 清空现有数据
            // 关联的 cgi 的 dgViewXwyCell kpi 明细
            if (selectedErrCell != null)
            {
                //string cgi = selectedErrCell.CGI;
                string ENI = selectedErrCell.ENI;
                string startDate = DateTime.Parse(selectedErrCell.StartDate).AddMonths(-1).ToString("yyyy-MM-dd");
                string endDate = DateTime.Parse(selectedErrCell.EndDate).AddMonths(1).ToString("yyyy-MM-dd");
                if (string.IsNullOrEmpty(ENI)) { return; }
                // 查询对应的kpi数据
                DataTable kpiData = _quertHelper.QueryDataBysql($"SELECT date,cgi,工参小区,eni,User,gb FROM kpixwy " +
                    $"WHERE ENI = '{ENI}' and Date >='{startDate}'and Date <='{endDate}'" +
                    $"order by date desc");

                if (kpiData != null && kpiData.Rows.Count > 0)
                {
                    dgViewLeftDownXwyNode.DataSource = kpiData;
                    dgViewLeftDownXwyNode.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
                }
                else
                {
                    //MessageBox.Show($"未找到CGI: {ENI} 的KPI数据");
                }
            }
        }

        private void updateTabControlLeftDownXwyCell()
        {
            dgViewLeftDownXwyCell.DataSource = null;
            dgViewLeftDownXwyCell.Rows.Clear(); // 清空现有数据
            // 关联的 cgi 的 dgViewXwyCell kpi 明细
            if (selectedErrCell != null)
            {
                //string cgi = selectedErrCell.CGI;
                string cgi = selectedErrCell.CGI;
                string startDate = DateTime.Parse(selectedErrCell.StartDate).AddMonths(-1).ToString("yyyy-MM-dd");
                string endDate = DateTime.Parse(selectedErrCell.EndDate).AddMonths(1).ToString("yyyy-MM-dd");
                if (string.IsNullOrEmpty(cgi)) { return; }
                // 查询对应的kpi数据
                DataTable kpiData = _quertHelper.QueryDataBysql($"SELECT date,cgi,工参小区,eni,User,gb FROM kpixwy " +
                    $"WHERE CGI = '{cgi}' and Date >='{startDate}'and Date <='{endDate}'" +
                    $"order by date desc");

                if (kpiData != null && kpiData.Rows.Count > 0)
                {
                    dgViewLeftDownXwyCell.DataSource = kpiData;
                    dgViewLeftDownXwyCell.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
                }
                else
                {
                    //MessageBox.Show($"未找到CGI: {ENI} 的KPI数据");
                }
            }
        }




        #endregion

        #region 右上
        private void updateRightUp()
        {
            DataTable ErrNode = _quertHelper.QueryDataBysql($"SELECT * FROM ErrNode " +
                    $"WHERE KeyId in (select ErrNodeKeyId from ErrCellNodeRelation where ErrCellKeyId = '{selectedErrCell.KeyId}')");
            if (ErrNode != null && ErrNode.Rows.Count > 0)
            {
                dgViewRightUp.DataSource = ErrNode;
                dgViewRightUp.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);

                dgViewRightUp.Rows[0].Cells[0].Selected = true;
                dgViewRightUp.CurrentCell = dgViewErrCell.Rows[0].Cells[0];

                var e = new DataGridViewCellEventArgs(0, 0);
                dgViewRightUp_CellClick(dgViewErrCell, e);
            }
            else
            {
                dgViewRightUp.DataSource = null;
                dgViewRightUp.Rows.Clear(); // 清空现有数据

                selectedErrNodeUp = null!;
            }
        }
        #endregion

        #region 右下
        private void updateRightDown()
        {
            DataTable ErrNode = _quertHelper.QueryDataBysql($"SELECT * FROM ErrNode " +
                    $"WHERE KeyId not in (select ErrNodeKeyId from ErrCellNodeRelation where ErrCellKeyId = '{selectedErrCell.KeyId}')" +
                    $"and ENI = '{selectedErrCell.ENI}'" +
                    $"and 开始日期 >='{DateTime.Parse(selectedErrCell.StartDate).AddDays(-10):yyyy-MM-dd}'" +
                    $"and 开始日期 <='{DateTime.Parse(selectedErrCell.EndDate).AddDays(10):yyyy-MM-dd}'");

            if (ErrNode != null && ErrNode.Rows.Count > 0)
            {
                dgViewRightDown.DataSource = ErrNode;
                dgViewRightDown.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);

                dgViewRightDown.Rows[0].Cells[0].Selected = true;
                dgViewRightDown.CurrentCell = dgViewErrCell.Rows[0].Cells[0];

                var e = new DataGridViewCellEventArgs(0, 0);
                dgViewRightDown_CellClick(dgViewErrCell, e);
            }
            else
            {

                dgViewRightDown.DataSource = null;
                dgViewRightDown.Rows.Clear(); // 清空现有数据

                selectedErrNodeDown = null!;
            }
        }

        #endregion


        #region 右键菜单初始化
        private void createMenuStrip()
        {
            #region 创建右上 ContextMenuStrip
            ContextMenuStrip customMenuRightUp = new ContextMenuStrip();

            ToolStripMenuItem itemOpen = new ToolStripMenuItem("新增");
            itemOpen.DropDownItems.AddRange(new ToolStripMenuItem[]
           {
                new ToolStripMenuItem("新增空白",null, (sender, e) => 新增ToolStripMenuItem_Click(sender, e)),
                new ToolStripMenuItem("优化",null,(new ToolStripMenuItem[]
                {
                    new ToolStripMenuItem("潮汐",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"潮汐")),
                    new ToolStripMenuItem("新兴区域-规划",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"新兴区域-规划")),
                    new ToolStripMenuItem("统计问题",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "统计问题")),
                    new ToolStripMenuItem("干扰问题",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "干扰问题")),
                    new ToolStripMenuItem("质差问题",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "质差问题")),
                    new ToolStripMenuItem("参数问题",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "参数问题")),
                    new ToolStripMenuItem("小区合并",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "小区合并")),
                    new ToolStripMenuItem("现场测试",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e, "现场测试")),
                })),
                new ToolStripMenuItem("维护",null,(new ToolStripMenuItem[]
                {
                    new ToolStripMenuItem("无线",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-无线")),
                    new ToolStripMenuItem("传输",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-传输")),
                    new ToolStripMenuItem("网调(室分)",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-网调-室分")),
                    new ToolStripMenuItem("网调(宏站)",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-网调-宏站")),
                    new ToolStripMenuItem("动力",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-动力")),
                    new ToolStripMenuItem("铁塔",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-铁塔")),
                    new ToolStripMenuItem("停业",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"维护-停业")),
                    new ToolStripMenuItem("资管问题",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"资管问题")),
                })),
                new ToolStripMenuItem("工程",null,(new ToolStripMenuItem[]
                {
                    new ToolStripMenuItem("工程(室分)",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"工程-室分")),
                    new ToolStripMenuItem("工程(宏站)",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"工程-宏站")),
                    new ToolStripMenuItem("传输",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"工程-传输")),
                    new ToolStripMenuItem("铁塔",null, (sender, e) => Add_ToolStripMenuItem_Click(sender, e,"工程-铁塔")),
                })),

           });


            ToolStripMenuItem itemUpdate = new ToolStripMenuItem("更新");
            itemUpdate.DropDownItems.AddRange(new ToolStripMenuItem[]
            {
                new ToolStripMenuItem("已处理",null, (sender, e) => 已处理ToolStripMenuItem_Click(sender, e)),
                new ToolStripMenuItem("已确认",null, (sender, e) => 已确认ToolStripMenuItem_Click(sender, e)),
                new ToolStripMenuItem( "重新处理",null, (sender, e) => 重新处理ToolStripMenuItem_Click(sender, e)),
                new ToolStripMenuItem("修改内容",null, (sender, e) => 更新ToolStripMenuItem_Click(sender, e))
            });
            ToolStripMenuItem itemDelete = new ToolStripMenuItem("删除");
            itemDelete.Click += (sender, e) => 删除ToolStripMenuItem_Click(sender, e);
            ToolStripMenuItem itemCancelRelation = new ToolStripMenuItem("取消关联");
            itemCancelRelation.Click += (sender, e) => 取消关联ToolStripMenuItem_Click(sender, e);



            customMenuRightUp.Items.AddRange([itemOpen, itemUpdate, itemDelete, itemCancelRelation]);
            dgViewRightUp.ContextMenuStrip = customMenuRightUp;

            #endregion

            #region 创建右下 ContextMenuStrip
            ContextMenuStrip customMenuRightDown = new ContextMenuStrip();
            ToolStripMenuItem itemDeleteRd = new ToolStripMenuItem("删除");
            itemDeleteRd.Click += (sender, e) => RD删除ToolStripMenuItem_Click(sender, e);
            ToolStripMenuItem itemAddRelation = new ToolStripMenuItem("添加关联");
            itemAddRelation.Click += (sender, e) => RD添加关联ToolStripMenuItem_Click(sender, e);

            customMenuRightDown.Items.AddRange([itemDeleteRd, itemAddRelation]);
            dgViewRightDown.ContextMenuStrip = customMenuRightDown;

            #endregion


            #region 左上Context
            ContextMenuStrip customMenuLeftUp = new ContextMenuStrip();
            ToolStripMenuItem itemUpdateGc = new ToolStripMenuItem("更新工参");
            itemUpdateGc.Click += (sender, e) => UpdateGcToolStripMenuItem_Click(sender, e);


            ToolStripMenuItem itemUpdateErrcellBh = new ToolStripMenuItem("闭环选中小区");
            itemUpdateErrcellBh.Click += (sender, e) => itemUpdateErrcellBhToolStripMenuItem_Click(sender, e);

            customMenuLeftUp.Items.AddRange([itemUpdateGc, itemUpdateErrcellBh]);
            dgViewErrCell.ContextMenuStrip = customMenuLeftUp;
            #endregion
        }

       
        #endregion

        #region 左上 右键菜单处理

        private void UpdateGcToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrCell == null) { return; }

            string cgi = selectedErrCell.CGI;
            string eni = selectedErrCell.ENI;

            FrmUpdateGc FrmUpdateGc = new(cgi, eni);
            FrmUpdateGc.Show();

        }

        private void itemUpdateErrcellBhToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            // 检查
            if (_db == null)
            {
                MessageBox.Show("数据库初始化失败");
                return;
            }
            // 循环所有被选中行
            Dictionary<int,string> dic = new Dictionary<int,string>();
            _db.BeginTransaction();
            foreach (DataGridViewCell cell in dgViewErrCell.SelectedCells)
            {
               
                if (!dic.TryGetValue(cell.RowIndex,out _))
                {
                    DataGridViewRow row = dgViewErrCell.Rows[cell.RowIndex];
                    ErrCell errCell = ErrCell.transtErrcellFromDataGridViewRow(row);
                    if (errCell.Status == "闭环?")
                    {
                        errCell.Status = "闭环";
                        _db.Update(errCell);
                    }
                    dic.Add(cell.RowIndex, "1");
                }
                
            }
            _db.Commit();
        }

        #endregion

        #region 右上 右键菜单处理
        private void 新增ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            // 判断是否选中质差小区
            if (selectedErrCell == null) { MessageBox.Show("选中质差小区后再操作"); return; }
            // 打开新增质差小区窗口
            FrmErrNode FrmErrNode = new("new");
            FrmErrNode.Show();
            // 传递选中的质差小区信息
            FrmErrNode.SetErrCell(selectedErrCell, this);


        }


        private void Add_ToolStripMenuItem_Click(object? sender, EventArgs e, string SetMode = "")
        {
            // 判断是否选中质差小区
            if (selectedErrCell == null) { MessageBox.Show("选中质差小区后再操作"); return; }
            // 打开新增质差小区窗口
            FrmErrNode FrmErrNode = new("new");
            FrmErrNode.Show();
            // 传递选中的质差小区信息
            FrmErrNode.SetErrCell(selectedErrCell, SetMode, this);


        }


        private void 更新ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }
            // 打开新增质差小区窗口
            FrmErrNode FrmErrNode = new("update");
            FrmErrNode.Show();
            // 传递选中的质差小区信息
            FrmErrNode.SetErrNode(selectedErrNodeUp, this);
        }

        private void 已处理ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            selectedErrNodeUp.Status = "已处理";
            // 设置处理时间为当前日期（如果为空）
            if (string.IsNullOrEmpty(selectedErrNodeUp.ProcessTime))
            {
                selectedErrNodeUp.ProcessTime = DateTime.Now.ToString("yyyy-MM-dd");
            }
               
            try
            {
                _db.Update(selectedErrNodeUp);
                // 更新右上列表
                updateRightUp();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新质差小区状态失败:{ex.Message}");
                return;
            }

            // 更新关联 ErrCell 的状态
            updateErrCellByNodeKey(selectedErrNodeUp.KeyId);

            // 更新左上 ErrCell
            updateLeftUp();

        }

        private void 已确认ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            selectedErrNodeUp.Status = "已确认";
            selectedErrNodeUp.ConfirmTime = DateTime.Now.ToString("yyyy-MM-dd");
            selectedErrNodeUp.ProcessTime = DateTime.Now.ToString("yyyy-MM-dd");
            selectedErrNodeUp.ConfirmPerson = "丁显强";
            try
            {
                _db.Update(selectedErrNodeUp);
                // 更新右上列表
                updateRightUp();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新质差小区状态失败:{ex.Message}");
                return;
            }

            // 更新关联 ErrCell 的状态
            updateErrCellByNodeKey(selectedErrNodeUp.KeyId);

            // 更新左上 ErrCell
            updateLeftUp();
        }

        private void 重新处理ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            selectedErrNodeUp.Status = "重新处理";
            try
            {
                _db.Update(selectedErrNodeUp);
                // 更新右上列表
                updateRightUp();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"更新质差小区状态失败:{ex.Message}");
                return;
            }

            // 更新关联 ErrCell 的状态
            updateErrCellByNodeKey(selectedErrNodeUp.KeyId);

            // 更新左上 ErrCell
            updateLeftUp();
        }


        private void 删除ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }
            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }

            var errCellKeyIds = _db.Table<ErrCellNodeRelation>()
               .Where(r => r.ErrNodeKeyId == selectedErrNodeUp.KeyId)
               .Select(r => r.ErrCellKeyId)
               .ToList();

            _db.RunInTransaction(() =>
            {
                _db.Execute($"DELETE FROM ErrCellNodeRelation WHERE ErrNodeKeyId = '{selectedErrNodeUp.KeyId}'"); // 删除关联关系
                _db.Delete(selectedErrNodeUp); // 删除 ErrNode
            });


            updateErrCellByCellKeys(errCellKeyIds);

            // 更新左上 ErrCell
            updateLeftUp();
        }

        private void 取消关联ToolStripMenuItem_Click(object? sender, EventArgs e)
        {


            if (selectedErrCell == null) { MessageBox.Show("选中质差小区后再操作"); return; }
            if (selectedErrNodeUp == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }

            var errCellKeyIds = _db.Table<ErrCellNodeRelation>()
               .Where(r => r.ErrNodeKeyId == selectedErrNodeUp.KeyId)
               .Select(r => r.ErrCellKeyId)
               .ToList();

            try
            {
                _db.Execute($"DELETE FROM ErrCellNodeRelation WHERE ErrNodeKeyId = '{selectedErrNodeUp.KeyId}' and ErrCellKeyId = '{selectedErrCell.KeyId}'"); // 删除关联关系
                // 更新右上列表
                updateRightUp();
                // 更新右下列表
                updateRightDown();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"取消关联失败:{ex.Message}");
                return;
            }

            updateErrCellByCellKeys([selectedErrCell.KeyId]);

            // 更新左上 ErrCell
            updateLeftUp();
        }
        #endregion

        #region 右下 右键菜单处理
        private void RD删除ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrCell == null) { MessageBox.Show("选中质差小区后再操作"); return; }
            if (selectedErrNodeDown == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }

            _db.RunInTransaction(() =>
            {
                _db.Execute($"DELETE FROM ErrCellNodeRelation WHERE ErrNodeKeyId = '{selectedErrNodeDown.KeyId}'"); // 删除关联关系
                _db.Delete(selectedErrNodeDown); // 删除 ErrNode
            });


            updateLeftUp();

        }

        private void RD添加关联ToolStripMenuItem_Click(object? sender, EventArgs e)
        {
            if (selectedErrCell == null) { MessageBox.Show("选中质差小区后再操作"); return; }
            if (selectedErrNodeDown == null) { MessageBox.Show("选中质差小区关联的质差小区后再操作"); return; }

            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }

            KpiTables.ErrCellNodeRelation rel = new()
            {
                ErrCellKeyId = selectedErrCell.KeyId,
                ErrNodeKeyId = selectedErrNodeDown.KeyId,
                KeyId = $"{selectedErrNodeDown.KeyId}_{selectedErrCell.KeyId}"
            };


            ErrNode errNode = _db.Table<ErrNode>()
                .FirstOrDefault(n => n.KeyId == selectedErrNodeDown.KeyId);

            errNode.ErrCellCount += 1; // 更新 ErrNode 的 ErrCellCount


            _db.RunInTransaction(() =>
            {
                _db.InsertOrReplace(rel);
                _db.Update(errNode); // 更新 ErrNode
            });


            updateErrCellByCellKeys([selectedErrCell.KeyId]);

            updateLeftUp();
        }
        #endregion

        #region 根据 ErrNode 更新 ErrCell 的状态
        // 根据更新的ErrNodeKeyId更新 ErrCell 的状态
        public void updateErrCellByNodeKey(string errNodeKeyId)
        {
            if (_db == null) { MessageBox.Show("数据库未初始化"); return; }
            // 根据 关联表 ErrCellNodeRelation 获取对应的 ErrCell
            var errCellKeyIds = _db.Table<ErrCellNodeRelation>()
                .Where(r => r.ErrNodeKeyId == errNodeKeyId)
                .Select(r => r.ErrCellKeyId)
                .ToList();

            if (errCellKeyIds.Count == 0) { return; } // 无关联 ErrCell

            updateErrCellByCellKeys(errCellKeyIds);
        }


        public void updateErrCellByCellKeys(List<string> keys)
        {
            if (_db == null) { return; }
            // 更新 ErrCell 的状态
            var errCells = _db.Table<ErrCell>()
                .Where(c => keys.Contains(c.KeyId))
                .ToList();

            _db.BeginTransaction();

            foreach (var errCell in errCells)
            {
                if (errCell.Status.StartsWith("闭环")) { continue; } // 闭环状态不更新

                // 查询关联的 ErrNode
                var relatedNodes = _db.Table<ErrCellNodeRelation>()
                    .Where(r => r.ErrCellKeyId == errCell.KeyId)
                    .Select(r => r.ErrNodeKeyId)
                    .ToList();

                // 取所有关联的 ErrNode 的状态 进度 最慢的状态 更新 
                if (relatedNodes.Count > 0)
                {


                    var LaseErrNode = _db.Table<ErrNode>()
                       .Where(n => relatedNodes.Contains(n.KeyId))
                       .ToList() // 加载到内存
                       .OrderByDescending(s => GetStatusRank(s.Status))
                       .FirstOrDefault();

                    if (LaseErrNode != null)
                    {

                        errCell.ProcessTime = LaseErrNode.ProcessTime; // 更新处理时间
                        errCell.Status = LaseErrNode.Status; // 更新 ErrCell 的状态

                        errCell.Problem = $"{LaseErrNode.ProblemLevel1}-{LaseErrNode.ProblemLevel2}";
                        errCell.ResponsibleDept = LaseErrNode.ResponsibleDept; // 更新责任部门
                        errCell.ResponsiblePerson = LaseErrNode.ResponsiblePerson; // 更新责任人

                        _db.Update(errCell); // 提交更新
                    }
                }
                else
                {
                    // 无关联 ErrNode，设置为默认状态

                    errCell.Problem = "待分析"; // 默认问题描述
                    errCell.ResponsibleDept = "待分配"; // 默认责任部门
                    errCell.ResponsiblePerson = "待分配"; // 默认责任人
                    errCell.ProcessTime = null; // 新增记录无处理时间
                    errCell.Status = "分析";

                    _db.Update(errCell);
                }

            }

            _db.Commit(); // 提交事务
        }



        private int GetStatusRank(string status) => status switch
        {
            "分发处理" => 1,
            "已处理" => 2,
            "已确认" => 3,
            "重新处理" => 2,
            _ => 0
        };
        #endregion


        #region 变化后刷新整个页面

        public void updateLeftUp()
        {
            //确保在UI线程执行
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(updateLeftUp));
                return;
            }


            string ErrName = CmbErrName.SelectedItem?.ToString() ?? "4G低流量";
            string ErrType = cmbErrType.SelectedItem?.ToString() ?? string.Empty;
            string cgi = txbErrcellCgi.Text.Trim();
            string eni = txbErrcellEni.Text.Trim();
            string isSchool = chbVacation.Checked ? "否" : string.Empty;//假期不分析学校
            string Status = cmbStatus.SelectedItem?.ToString() ?? string.Empty;

            int r = dgViewErrCell.CurrentCell != null ? dgViewErrCell.CurrentCell.RowIndex : 0;
            int c = dgViewErrCell.CurrentCell != null ? dgViewErrCell.CurrentCell.ColumnIndex : 0;

            //MessageBox.Show($"加载{ErrName}");

            RefreshErrCellList(ErrName, cgi, eni, ErrType, Status: Status, isSchool: isSchool);


            if (dgViewErrCell.Rows.Count == 0)
            {
                labelStatus.Text = $"没有检索到数据 cgi:{(string.IsNullOrEmpty(cgi) ? "空" : cgi)};" +
                    $"eni:{(string.IsNullOrEmpty(eni) ? "空" : eni)}," +
                    $"质差名称:{(string.IsNullOrEmpty(ErrName) ? "空" : ErrName)}," +
                    $"质差类型:{(string.IsNullOrEmpty(ErrType) ? "空" : ErrType)}," +
                    $"状态:{(string.IsNullOrEmpty(Status) ? "空" : Status)}," +
                    $"学校:{(string.IsNullOrEmpty(isSchool) ? "空" : isSchool)}";
                return;
            }

            r = r > dgViewErrCell.Rows.Count ? 0 : r;
            c = r > dgViewErrCell.Columns.Count ? 0 : c;


            dgViewErrCell.ClearSelection();
            //dgViewErrCell.Rows[0].Selected = true;
            //dgViewErrCell.Rows[r].Cells[0].Selected = true;


            // 手动触发 CellClick 事件
            //var e = new DataGridViewCellEventArgs(r, c); // 参数：列索引, 行索引
            //dgViewErrCell_CellClick(dgViewErrCell, e);
        }


        // 刷新错误小区列表
        private void RefreshErrCellList(string errName, string cgi = "", string eni = "", string ErrType = "", string Status = "", string isSchool = "")
        {
            if (_db == null) return;

            // 新增查询条件：根据 cgi 和 eni 过滤
            List<ErrCell> query = _db.Table<ErrCell>()
                .Where(c => c.ErrName == errName)
                .ToList();


            // 添加 cgi 条件（非空时生效）
            if (!string.IsNullOrEmpty(cgi))
            {
                query = query.Where(c => c.CGI == cgi).ToList(); // 假设字段名为 CGI
            }

            // 添加 eni 条件（非空时生效）
            if (!string.IsNullOrEmpty(eni))
            {
                query = query.Where(c => c.ENI == eni).ToList(); // 假设字段名为 ENI
            }

            // 添加 eni 条件（非空时生效）
            if (!string.IsNullOrEmpty(ErrType))
            {
                query = query.Where(c => c.ErrType == ErrType).ToList(); // 假设字段名为 ENI
            }

            // 添加 Status 条件（非空时生效）
            if (!string.IsNullOrEmpty(Status))
            {
                switch (Status)
                {
                    case "当日新增":
                        query = query.Where(c => c.StartDate == DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd")).ToList();
                        break;
                    case "当日恢复":
                        query = query.Where(c => c.EndDate == DateTime.Now.AddDays(-2).ToString("yyy-MM-dd") && c.Status.Contains("闭环")).ToList();
                        break;
                    case "最新恢复":
                        string maxDate = _db.ExecuteScalar<string>($"SELECT 结束日期 FROM ErrCell where 质差名称='{ErrName}' and 状态 like '%闭环' ORDER BY 结束日期 DESC LIMIT 1");
                        query = query.Where(c => c.EndDate == maxDate && c.Status.Contains("闭环")).ToList();
                        break;
                    case "未闭环":
                        query = query.Where(c => c.Status != "闭环").ToList();
                        break;
                    default:
                        query = query.Where(c => c.Status == Status).ToList();
                        break;
                }

            }

            // 添加 isSchool 条件（非空时生效）
            if (!string.IsNullOrEmpty(isSchool))
            {
                query = query.Where(c => c.IsSchool == (isSchool == "是" ? 1 : 0)).ToList(); // 假设字段名为 IsSchool
            }


            // 绑定到 BindingSource
            _bdErrCell.DataSource = query;
            //dgViewErrCell.Refresh(); // 强制刷新显示

        }

        #endregion

        #region 假期复选框处理
        private void chbVacation_CheckedChanged(object sender, EventArgs e)
        {
            updateLeftUp();
        }
        #endregion
    }
}
